home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / ANTENNA / YAGIU112 / OUTPUT.C < prev    next >
C/C++ Source or Header  |  1995-08-07  |  7KB  |  211 lines

  1. /*
  2. A few changes have been made, including:
  3. 1) Memory is freed, rather than lying on the OS
  4. 2) Memory is no longer repeatdly allocated, which meant excessive use 
  5. of system memory.
  6. */
  7. #include <stdio.h>
  8. #include <malloc.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <sys/types.h>
  12. #include "yagi.h"
  13.  
  14. double Zo=Z0; /* Z0 is defined in yagi.h */
  15.  
  16. extern int optind, opterr;
  17. extern char *optarg;
  18. double min_offset_from_peak, angular_stepsize_2; /* not needed */
  19.  
  20. double pin, design_f, normalised_f, f;
  21. double gain_E_plane, gain_H_plane, peak_gain;
  22. struct element_data *coordinates;
  23. struct FCOMPLEX *current;
  24. int elements;
  25.  
  26.  
  27.  
  28. int main(int argc, char **argv)
  29. {
  30.     FILE *ifp, *ofp, *gain_fp;
  31.     char *input_filename, *output_filename, *temp;
  32.     char *gain_filename;
  33.     double min_f, max_f, step_f, vswr, angular_step;
  34.     double magnitude, phase,max_SL,E_max=E_MAX, H_max=H_MAX;
  35.     struct FCOMPLEX *voltage, input_impedance;
  36.     double fb_ratio,gain_E_plane_back;
  37.     double gain_H_plane_back;
  38.     struct flags flag;
  39.     struct pattern pattern_shape;
  40.     double x;
  41.     int k=1, c;
  42.     input_filename=string(0L, 100L);
  43.     output_filename=string(0L, 100L);
  44.     gain_filename=string(0L, 100L);
  45.     memset((char *) &flag, 0, sizeof(flag));
  46.    while ((c =  getoptions(argc,argv,"cehsE:H:Z:")) != -1)
  47.    switch       (c) 
  48.    {      case 'c':
  49.                   flag.cflg=1;
  50.                   break;
  51.              case 'e':  /* suppress E- plane 3dB BW */
  52.                     flag.eflg=1;
  53.                   break;
  54.              case 'h':  /* suppress H- plane 3dB BW */
  55.                     flag.hflg=1;
  56.                   break;
  57.              case 's':   /* suppress diagnostics */
  58.                     flag.sflg=1;
  59.                   break;
  60.           case 'E':             /* Max angle in E plane to look for -3dB */
  61.                   E_max=atof(optarg);
  62.                break;
  63.           case 'H':
  64.                H_max=atof(optarg); /* max angle in H plane to look for -3dB */
  65.                break;
  66.           case 'Z':        /* Zo */
  67.                Zo=atof(optarg);
  68.                break;
  69.              case '?':   /* default */
  70.                     flag.errflg=1;
  71.                     break;
  72.     }
  73.     if((argc-optind != 1) || flag.errflg)
  74.     {
  75.         usage_output(argv[0]);
  76.         exit(0);
  77.     }
  78.     /* The file read by 'output' is expected to have a .out extension.
  79.     'output' creates files with extensions:
  80.     .dat     Containing the basic broperties of impedance, gain etc as a function
  81.          of frequency.
  82.     .gai     Contains field patterns (gain) in the both H and E plane.
  83.     
  84.     We here get all the file names, then open files. */
  85.     strcpy(input_filename, argv[optind]);
  86.     strcpy(output_filename, *(argv+optind));
  87.     strcpy(gain_filename, *(argv+optind));
  88.        
  89.     strcat(input_filename,".out");
  90.     strcat(output_filename,".dat");
  91.     strcat(gain_filename,".gai");
  92.     ifp=fopen(input_filename,"rb");
  93.     ofp=fopen(output_filename,"wb");
  94.     gain_fp=fopen(gain_filename,"wt");
  95.     if(ifp == NULL)
  96.     {
  97.         fprintf(stderr,"Cant open %s\n", input_filename);
  98.         exit(10);
  99.     }
  100.  
  101.     temp=string(0L,100L);
  102.     /* No longer need to refer to files by names, we just use the 
  103.     file pointers, so free memory associated with names. */
  104.     free_string(output_filename,0L,100L);
  105.     free_string(gain_filename,0L,100L);
  106.     /* Read the header on the .out file, which is usually 100 Bytes,
  107.     but can be defined in yagi.h as HEADER_SIZE */
  108.     elements=read_header(ifp, ofp, &min_f, &max_f, &step_f, &design_f, &angular_step);
  109.     /* Creatre an array of structures, so contain the x and y locations of 
  110.     each element, and the lengths of the elements. All dimensions are in m */
  111.     coordinates=element_data_vector(1,elements); /* x,y &l of centre of ele's */
  112.     /* read into memory the x,y, and lengths of all elements */
  113.     fread((char *) &coordinates[1], sizeof(struct element_data),elements,ifp);
  114.     /* Create arrays to hold real and imaginary components of voltage */
  115.     voltage=FCOMPLEXvector(1,elements);
  116.     current=FCOMPLEXvector(1,elements);
  117.     /* read voltages applied to elements into memory */
  118.     fread((char *) &voltage[1], sizeof(struct FCOMPLEX),elements, ifp);
  119.     /* Now print a one line header to put into .dat file */
  120.     fprintf(ofp,"  f(MHz) E(deg) H(deg)  R     jX     SWR   Gain(dBi)     FB(dB)    SideLobes(dB)\n");
  121.     /* compute data at every frequency of interest */
  122.     for(f=min_f; f<=max_f; f+=step_f)
  123.     {
  124.         normalised_f=f/design_f;
  125.         fread((char *) ¤t[1], sizeof(struct FCOMPLEX),elements, ifp);
  126.         z_input(voltage[1], current[1], &input_impedance);
  127.         /* Compute magnitude and phase of reflection coefficient */
  128.         reflection_coefficient(input_impedance, &magnitude, &phase);
  129.         /* Compute VSWR from magnitude of reflection coefficient */
  130.         vswr=calculate_vswr(magnitude);
  131.         /* Calculate power input to antenna */
  132.         pin=calculate_power_input(input_impedance.r,current[1]); /* in Watts */
  133.         if(pin < 0.0)
  134.         {
  135.             fprintf(stderr,"input power less than 0! Probably due to self or mutual impedance being inaccurate when current not sinusidal\n");
  136.             fprintf(stderr,"f=%lf MHz Zin=%lf +i%lf\n",f/1e6, input_impedance.r, input_impedance.i);
  137.         }
  138.         /* compute gain at theta=90, phi=0 (forward direction) */
  139.         gain(90, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
  140.         /* compute gain at theta -90 degrees (ie back - direction) */
  141.         gain(270, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane_back, &gain_H_plane_back, f, design_f); 
  142.         fb_ratio=gain_E_plane-gain_E_plane_back;  /* in dB, so subtract */
  143.         /* If the values of impedance are too large, the cant be printed in
  144.         the .dat file. Hence we truncate them. At this point, the numbers
  145.         are so large, that we are not likely to be able to use them anyway. */
  146.         if(input_impedance.r > 9999999)
  147.             input_impedance.r = 9999999;
  148.         if(input_impedance.i > 9999999)
  149.             input_impedance.i = 9999999;
  150.         if(input_impedance.r < -9999999)
  151.             input_impedance.r = -9999999;
  152.         if(input_impedance.i < -9999999)
  153.             input_impedance.i = -9999999;
  154.     
  155.        /* Find the most importent bits of the pattern info */
  156.  
  157.         /* Estimiate 3dB bandwidth using .See '-E' and '-H' options */
  158.         peak_gain=gain_E_plane;
  159.         if(flag.hflg || elements==1)
  160.             pattern_shape.three_dB_H=0.0;  
  161.         else
  162.           pattern_shape.three_dB_H=(double) zbrent(error_3dB_H, 0.0,H_max,0.1);  
  163.         if(flag.eflg)
  164.             pattern_shape.three_dB_E=0.0;  
  165.         else
  166.              pattern_shape.three_dB_E=(double) zbrent(error_3dB_E, 90.0,E_max,0.1); 
  167.         if(flag.cflg==1)
  168.         {
  169.             max_SL=find_max_sidelobe_slow(peak_gain, pin,coordinates,current,elements,f,design_f); 
  170.         }
  171.         else
  172.             max_SL=0.0;
  173.         fprintf(ofp,"%9.3lf %3.1lf  %3.1lf %6.2lf %6.2lf %6.3lf %10.3lf %10.3lf %10.3lf\n",f/1e6,2*(pattern_shape.three_dB_E-90), 2*pattern_shape.three_dB_H,input_impedance.r, input_impedance.i, vswr, peak_gain, fb_ratio,max_SL);
  174.         write_gain_at_various_angles(gain_fp, angular_step, pin, normalised_f, f, coordinates, current, elements, design_f); 
  175.         if((min_f < max_f) && !flag.sflg)
  176.             printf("%s compleated  %5.1lf%%\n",argv[0],100*(f-min_f)/(max_f-min_f));
  177.     }
  178.     /* free strings not already freed */
  179.     free_string(input_filename,0L,100L);
  180.     free_string(temp,0L,100L);
  181.     
  182.     /* free vectors */
  183.     free_FCOMPLEXvector(voltage,1L,(long) elements);
  184.     free_FCOMPLEXvector(current,1L,(long) elements);
  185.  
  186.     fclose(ifp); 
  187.     
  188.     fclose(gain_fp);
  189. }
  190.  
  191.  
  192.  
  193. double error_3dB_E(double x)
  194. {
  195.         double ans;
  196.  
  197.         gain(x, 0, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
  198.         ans=peak_gain-gain_E_plane-3.01;
  199.         return(ans);
  200. }
  201.  
  202. double error_3dB_H(double x)
  203. {
  204.         double ans;
  205.  
  206.         gain(0, x, pin, normalised_f, coordinates, current, elements, &gain_E_plane, &gain_H_plane, f, design_f );
  207.         ans=peak_gain-gain_H_plane-3.01;
  208.         return(ans);
  209. }
  210.  
  211.